#ifndef REQUEST_HH
# define REQUEST_HH

#include "../math/vector.hh"

#include <boost/enable_shared_from_this.hpp>

//sending objects:
//id
//pos3d
//whatismyobject.

#include <boost/shared_ptr.hpp>

#include <iostream>
#include <list>

class RequestHandler;

class Request: public boost::enable_shared_from_this<Request>
{
public:
  virtual ~Request () {}

  virtual void operator() (RequestHandler* rh, const int* clientid = 0) = 0;
};

class GetObject: public Request
{
public:
  virtual ~GetObject () = 0;

  virtual void operator() (RequestHandler* rh, const int* clientid = 0);

  int objectid () const { return objectid_; }

protected:
  int objectid_;
};

class AskMap: public Request
{
public:
  virtual void operator() (RequestHandler* rh, const int* clientid = 0);
};

class Connection: public Request
{
public:
  virtual ~Connection () = 0;
  virtual void operator() (RequestHandler* rh, const int* clientid = 0);
};

class Disconnection: public Request
{
public:
  virtual void operator() (RequestHandler* rh, const int* clientid = 0);
};

class GetAllObjects: public Request
{
public:
  virtual void operator() (RequestHandler* rh, const int* clientid = 0);
};

class Text: public Request
{
public:
  Text (const std::string& data);

  const std::string& text () const { return text_; }

  virtual void operator() (RequestHandler* rh, const int* clientid = 0);
protected:
  std::string text_;
};

class UpdateObj: public Request
{
public:
  UpdateObj (const std::string& data);
  UpdateObj (int objid);

  virtual void operator() (RequestHandler* rh, const int* clientid = 0);

  const Vector3f& newpos () const { return newpos_; }
  const Vector3d& rot () const { return rot_; }
  int objid () const { return objid_; }

protected:
  int objid_;
  Vector3f newpos_;
  Vector3d rot_;
};

class UpdatePos: public Request
{
public:
  UpdatePos (const std::string& data);

  virtual void operator() (RequestHandler* rh, const int* clientid = 0);

  unsigned char pos_x () const { return pos_x_; }
  unsigned char pos_y () const { return pos_y_; }

protected:
  unsigned char pos_x_;
  unsigned char pos_y_;
};

class GameMode: public Request
{
public:
  enum GameType { Unknown, Fps, Rts };

  GameMode (const std::string& data);

  virtual void operator() (RequestHandler* rh, const int* clientid = 0);

  GameType mode () const { return mode_; }

protected:
  GameType mode_;
};

class GameZone: public Request
{
public:
  GameZone (const std::string& data);

  virtual void operator() (RequestHandler* rh, const int* clientid = 0);

  bool destroy () const { return destroy_; }
  const Vector3f& pos () const { return pos_; }
  const Vector3f& size () const { return size_; }

protected:
  bool destroy_;
  Vector3f pos_;
  Vector3f size_;
};

class Ready: public Request
{
public:
  virtual void operator() (RequestHandler* rh, const int* clientid = 0);
};

class Move: public Request
{
public:
  Move (const std::string& data);
  virtual void operator() (RequestHandler* rh, const int* clientid = 0);
  std::list<Vector3f> waypoints ();
  int id ();
protected:
  std::list<Vector3f> waypoints_;
  size_t size_;
  size_t req_size_;
  int id_;
};
#endif /// !REQUEST_HH
